/**
 *
 */
package com.lgCore.rpc.common.codec;

import com.lgCore.protoModel.ProtoMsg;
import com.lgCore.util.ByteObjUtil;
import com.lgCore.util.ByteUtil;
import com.lgCore.util.ProtoByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.Date;
import java.util.List;

/**
 * 解码 处理粘包和断包问题
 *
 * @author ligang
 */
public class CommonRpcDecoderHandler extends ByteToMessageDecoder {
    //数据包基础长度
    private final int MINLENTH = 7;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf buf,
                          List<Object> out) throws Exception {
        try {
            Date date = new Date();
            //基础长度不足，标识符和长度 7位
            if (buf.readableBytes() < MINLENTH) {
                return;
            }
            int beginIdx; //记录包头位置

            //打印日志
//            System.out.println(buf.isReadable());


//            while (true) {
//                // 获取包头开始的index
//                beginIdx = buf.readerIndex();
//                // 标记包头开始的index
//                buf.markReaderIndex();
//                // 读到了协议的开始标志，结束while循环
//                if (buf.readByte() == 0x02) {
//                    break;
//                }
//                // 未读到包头，略过一个字节
//                // 每次略过，一个字节，去读取，包头信息的开始标记
//                // 重置读取位置
//                buf.resetReaderIndex();
//
//                buf.readByte();
//                // 当略过，一个字节之后，
//                // 数据包的长度，又变得不满足
//                // 此时，应该结束。等待后面的数据到达
//                if (buf.readableBytes() < MINLENTH) {
//                    return;
//                }
//
//            }


            // 获取包头开始的index
            beginIdx = buf.readerIndex();
            if (beginIdx == buf.writerIndex()) {
                //读和写指针一样
                return;
            }
            // 标记包头开始的index
            buf.markReaderIndex();
            // 读到了协议的开始标志，结束while循环
            if (buf.readByte() != 0x02) {
                // 重置之前的读取位置
                buf.resetReaderIndex();
                return;
            }
            // 未读到包头，略过一个字节
            // 当略过，一个字节之后，
            // 数据包的长度，又变得不满足
            // 此时，应该结束。等待后面的数据到达
            if (buf.readableBytes() < MINLENTH) {
                // 重置之前的读取位置
                buf.resetReaderIndex();
                return;
            }
            //剩余长度不足可读取数量[没有内容长度位]
            int readableCount = buf.readableBytes();
            if (readableCount <= 6) {
                // 重置之前的读取位置
                buf.resetReaderIndex();
                return;
            }

            /****************读取内容 start*****************/
//            buf.readBytes(1);
            //获取内容长度
            byte[] numDataByte = new byte[6];
            buf.readBytes(numDataByte);
            int num = ByteUtil.bytes2Int(numDataByte);
//            System.out.println(num);
            readableCount = buf.readableBytes();
            if (readableCount < num) {
                buf.readerIndex(beginIdx);
                return;
            }
            byte[] dataByte = new byte[num];
            buf.readBytes(dataByte);
//            Object result=null;
            ProtoMsg.Message message = ProtoByteUtil.byteToProto(dataByte);
            Object result = message;
//                    Object result = CommonRpcCodecs.getDecoder(CommonRpcCodecs.KRYO_CODEC).decode(null, dataByte);
            if (result != null) {
                out.add(result);
//                long times = new Date().getTime() - date.getTime();
//                if (times > 1) {
//                    System.out.println("readerIndex:" + buf.readerIndex() + "----" + "writerIndex:" + buf.writerIndex()
//                            + "----" + "capacity:" + buf.capacity());
//                    System.out.println("解码时间" + times);
//                }

            }
            /**************读取内容 end*****************/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
